const Model = require('./index')

class PermissionModel extends Model {
  /**
   * 角色列表查询
   * @param {*} andConditions
   * @param {*} orConditions
   */
  async findRoles (conditions) {
    const completeSql = this.generateWhereClause(conditions)
    const sql = `select * from role ${completeSql}`
    try {
      const data = await this.db.query(sql)
      return data
    } catch (error) {
      throw new Error(error)
    }
  }

  /**
   * 角色新增
   * @param {*} attrs
   */
  async createRole (attrs) {
    const { name, status } = attrs
    const createTime = this.dateFormat(new Date())
    const sql = `insert into role (name, status, type, createTime) 
      values(?, ?, ?, ?)`
    try {
      await this.db.query(sql, [name, status, '1', createTime])
    } catch (error) {
      throw new Error(error)
    }
  }

  /**
   * 角色编辑
   * @param {*} id
   * @param {*} attrs
   */
  async updateRole (id, attrs) {
    const { name, status } = attrs
    const updateTime = this.dateFormat(new Date())
    const sql = 'update role set name = ?, status = ?, updateTime = ? where id = ?'
    try {
      await this.db.query(sql, [name, status, updateTime, id])
    } catch (error) {
      throw new Error(error)
    }
  }

  /**
   * 角色删除同时删除该角色下的所有权限资源和员工下的该角色
   * @param {*} id
   */
  async deleteRole (id) {
    const sql = `delete role, role_permission, staff_role from role
      left join role_permission on role_permission.roleId = role.id
      left join staff_role on staff_role.roleId = role.id
      where role.id = ?`
    try {
      await this.db.query(sql, [id])
    } catch (error) {
      throw new Error(error)
    }
  }

  /**
   * 查询当前角色下存在的资源权限列表
   * @param {*} roleId
   */
  async findRolePermission (roleId) {
    // 前端回显需要，只返回最后一层资源
    const sql = `select permissionId from role_permission 
      where permissionId not in (select distinct parentId from resource where parentId is not null) 
      and roleId = ?`
    try {
      const data = await this.db.query(sql, [roleId])
      return data
    } catch (error) {
      throw new Error(error)
    }
  }

  async findOneRole (id) {
    const sql = 'select * from role where id = ?'
    try {
      const data = await this.db.query(sql, [id])
      return data[0]
    } catch (error) {
      throw new Error(error)
    }
  }

  async existRole (id) {
    const sql = 'select id from role where id = ?'
    try {
      const data = await this.db.query(sql, [id])
      return Boolean(data[0])
    } catch (error) {
      throw new Error(error)
    }
  }

  /**
   * 角色权限分配
   * @param {*} roleId
   * @param {*} permissionIds
   */
  async createRolePermission (roleId, permissionIds) {
    const batchInsert = permissionIds.map(id => {
      return `(${roleId}, ${id})`
    }).join(',')
    const deleteSql = `delete from role_permission where roleId = ${roleId}`
    const insertSql = `insert into role_permission (roleId, permissionId) values ${batchInsert}`
    try {
      await this.db.query(deleteSql)
      if (permissionIds?.length) {
        await this.db.query(insertSql)
      }
    } catch (error) {
      throw new Error(error)
    }
  }

  /**
   * 用户角色分配
   * @param {*} staffId
   * @param {*} roleIds
   */
  async createStaffRole (staffId, roleIds) {
    const batchInsert = roleIds.map(id => {
      return `(${staffId}, ${id})`
    }).join(',')
    const deleteSql = `delete from staff_role where staffId = ${staffId}`
    const insertSql = `insert into staff_role (staffId, roleId) values ${batchInsert};`
    try {
      await this.db.query(deleteSql)
      await this.db.query(insertSql)
    } catch (error) {
      throw new Error(error)
    }
  }

  /**
   * 根据员工id查询该员工下面所有可用角色的资源权限码
   * @param {*} staffId
   */
  async findPermissionByStaffId (staffId) {
    const sql = `select distinct resource.code from resource where resource.id in 
      (select rp.permissionId from role_permission rp where rp.roleId in 
        (select sr.roleId from staff_role sr join role on (role.id = sr.roleId and role.status = '1') where sr.staffId = ${staffId})
      )`
    try {
      const data = await this.db.query(sql)
      return data
    } catch (error) {
      throw new Error(error)
    }
  }
}

module.exports = new PermissionModel()
